﻿namespace MicroCloud.Entity
{
    /// <summary>
    /// 数据库连接字符串提供者
    /// </summary>
    public class ConnectionStringProvider : IConnectionStringProvider
    {
        //字段
        private readonly IDictionary<string, DbContextOption> _dbContexts;
        private readonly ISlaveDatabaseSelector[] _slaveDatabaseSelectors;
        private readonly IMasterSlaveSplitPolicy _masterSlavePolicy;

        #region 构造函数
        /// <summary>
        /// 初始化一个<see cref="ConnectionStringProvider"/>类型的新实例
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public ConnectionStringProvider(IServiceProvider provider)
        {
            _dbContexts = provider.GetMicroCloudOptions().DbContexts;
            _masterSlavePolicy = provider.GetService<IMasterSlaveSplitPolicy>();
            _slaveDatabaseSelectors = provider.GetServices<ISlaveDatabaseSelector>().ToArray();
        }

        #endregion

        #region 方法
        /// <summary>
        /// 获取指定数据上下文类型的数据库连接字符串
        /// </summary>
        /// <param name="dbContextOption">数据上下文配置选项</param>
        /// <returns></returns>
        public virtual string GetConnectionString(DbContextOption dbContextOption)
        {
            bool isSlave = _masterSlavePolicy.IsToSlaveDatabase(dbContextOption);
            if (!isSlave)
            {
                return dbContextOption.ConnectionString;
            }

            SlaveDatabaseInfo[] slaveDatabases = dbContextOption.SlaveDatabase.SlaveDatabases;
            ISlaveDatabaseSelector slaveDatabaseSelector = _slaveDatabaseSelectors.LastOrDefault(m => m.SelectorType == dbContextOption.SlaveDatabase.SlaveSelectorEnum)
                ?? _slaveDatabaseSelectors.First(m => m.SelectorType == SlaveDatabaseSelectorType.Weight);
            SlaveDatabaseInfo slaveDatabase = slaveDatabaseSelector.Select(slaveDatabases);
            return slaveDatabase.ConnectionString;
        }

        #endregion

    }

}
